package settings

import (
	"fmt"
	"github.com/go-redis/redis"
	_ "github.com/go-sql-driver/mysql"
	"github.com/go-xorm/core"
	"github.com/go-xorm/xorm"
)

type mysqlInfo struct {
	User     string
	Password string
	Host     string
	Db       string
	//TablePrefix string
	MaxIdle float64
	MaxCon  float64
	Show    bool
	Level   float64
	Charset string
}

type Server struct {
	RunMode      string
	HttpPort     float64
	ReadTimeOut  float64
	WriteTimeOut float64
}

type LogInfo struct {
	LogPath    string
	LogName    string
	LogExt     string
	TimeFormat string
}

type App struct {
	PageSize   float64
	AllowSize  float64
	ExportPath string
	RootPath   string
}

type Jwt struct {
	JwtSecret string
	Expire    float64
}

type Redis struct {
	Host        string
	Password    string
	MaxIdle     float64
	MaxActive   float64
	IdleTimeOut float64
}

var (
	ServerBase  = Server{}
	LogBase     = LogInfo{}
	SqlBaseInfo = mysqlInfo{}
	MasterDB    *xorm.Engine
	AppBase     = App{}
	JwtBase     = Jwt{}
	redisBase   = Redis{}
)

const (
	RDb0 = iota //0 黑白名单
	RDb1
	RDb2
	RDb3
	RDb4
	RDb5 //保存用户topt信息

	StringFlag  = "-1"
	PrefixPer   = "per_"
	PrefixToken = "token_"
	Empty       = ""
	Zero        = 0
	Update      = "update"
	Add         = "add"
	Delete      = "delete"
	PrefixBlack = "BLOCK_"
	PrefixTable = "web_"
)

func SetUpConf(path string) {

	mysqlBase := GetConfig("mysql", path).(map[string]interface{})

	server := GetConfig("server", path).(map[string]interface{})
	log := GetConfig("log", path).(map[string]interface{})
	app := GetConfig("app", path).(map[string]interface{})
	jwt := GetConfig("jwt", path).(map[string]interface{})
	rds := GetConfig("redis", path).(map[string]interface{})

	MapToStruct(log, &LogBase)

	MapToStruct(mysqlBase, &SqlBaseInfo)
	MapToStruct(server, &ServerBase)
	MapToStruct(app, &AppBase)
	MapToStruct(jwt, &JwtBase)
	MapToStruct(rds, &redisBase)
	mysqlDns()

}

func mysqlDns() {
	dns := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8&parseTime=True&loc=Local",
		SqlBaseInfo.User,
		SqlBaseInfo.Password,
		SqlBaseInfo.Host,
		SqlBaseInfo.Db)
	if err := initEngine(dns); err != nil {
		panic(err)
	}
}

func initEngine(dns string) error {
	var err error
	MasterDB, err = xorm.NewEngine("mysql", dns)
	ping := MasterDB.Ping()
	if err != nil || ping != nil {
		fmt.Println("mysql", ping, err)
		panic(ping)
	}

	maxIdle := SqlBaseInfo.MaxIdle
	maxConn := SqlBaseInfo.MaxCon
	MasterDB.SetMaxIdleConns(int(maxIdle))
	MasterDB.SetMaxOpenConns(int(maxConn))
	showSQL := SqlBaseInfo.Show
	logLevel := SqlBaseInfo.Level

	tbMapper := core.NewPrefixMapper(core.SnakeMapper{}, PrefixTable)
	MasterDB.SetTableMapper(tbMapper)
	MasterDB.ShowSQL(showSQL)
	MasterDB.Logger().SetLevel(core.LogLevel(logLevel))

	// 启用缓存
	// cacher := xorm.NewLRUCacher(xorm.NewMemoryStore(), 1000)
	// MasterDB.SetDefaultCacher(cacher)
	return nil
}

func RedisConn(db int) *redis.Client {

	Client := redis.NewClient(&redis.Options{
		Addr:     redisBase.Host,
		Password: redisBase.Password,
		DB:       db,
		PoolSize: int(redisBase.MaxActive),
	})

	_, err := Client.Ping().Result()
	if err != nil {
		panic(err)
	}
	return Client
}
